/**
  **********************************************************************************************************************
  * @file    queue.h
  * @brief   该文件提供单向队列FIFO所有函数原型
  * @author  const_zpc    any question please send mail to const_zpc@163.com
  * @version V0.1
  * @date    2023-03-26
  **********************************************************************************************************************
  *
  **********************************************************************************************************************
  */

/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/

#ifndef _COT_CONTAINER_QUEUE_H_
#define _COT_CONTAINER_QUEUE_H_

/* Includes ----------------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#ifdef __cplusplus
 extern "C" {
#endif 


typedef struct
{
    uint8_t *pBuf;
    size_t  itemSize;
    size_t  limit;
    size_t  wIdx;
    size_t  rIdx;
    bool    isEmpty;
} cotQueue_t;


#define COT_Queue_Define(name, limt, T)  static queue_##name##_buf[limt * sizeof(T)];\
                                        static cotQueue_t queue_##name = {queue_##name##_buf, sizeof(T), limt, 0, 0, true};

#define COT_Queue_Empty(name)        cotQueue_Empty(&name)
#define COT_Queue_Size(name)         cotQueue_Size(&name)
#define COT_Queue_Front(name, T)     *(T *)cotQueue_Front(&name)
#define COT_Queue_Back(name, T)      *(T *)cotQueue_Back(&name)
#define COT_Queue_Push(name, T, V)   cotQueue_Push(&name, &V, sizeof(T));
#define COT_Queue_Pop(name)          cotQueue_Pop(&name);


extern void cotQueue_Init(cotQueue_t *pQueue, uint8_t *pBuf, size_t bufSize, size_t itemSize);

extern bool cotQueue_Empty(cotQueue_t *pQueue);
extern bool cotQueue_Full(cotQueue_t *pQueue);
extern size_t cotQueue_Size(cotQueue_t *pQueue);

extern void *cotQueue_Front(cotQueue_t *pQueue);
extern void *cotQueue_Back(cotQueue_t *pQueue);
extern int cotQueue_Push(cotQueue_t *pQueue, const void *pdata, size_t length);
extern int cotQueue_Pop(cotQueue_t *pQueue);

extern void cotQueue_Swap(cotQueue_t *pQueue, cotQueue_t *pNewQueue);



#ifdef __cplusplus
 }
#endif

#endif // !_COT_CONTAINER_QUEUE_H_
